<template>
  <el-form ref="formRef" :model="formData" :rules="formRules" label-width="150px">
    <el-row>
      <el-col :span="12">
        <el-form-item label="生成模版" prop="templateType">
          <el-select v-model="formData.templateType">
            <el-option
              v-for="dict in infra_codegen_template_type"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="前端类型" prop="frontType">
          <el-select v-model="formData.frontType">
            <el-option
              v-for="dict in infra_codegen_front_type"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="生成场景" prop="scene">
          <el-select v-model="formData.scene">
            <el-option
              v-for="dict in infra_codegen_scene"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item prop="parentMenuId">
          <template #label>
            <span>
              上级菜单
              <el-tooltip content="分配到指定菜单下，例如 系统管理" placement="top">
                <Icon icon="ep:question-filled" />
              </el-tooltip>
            </span>
          </template>
          <el-tree-select
            v-model="formData.parentMenuId"
            :data="menuTree"
            :props="{ ...defaultProps, label: 'name2' }"
            :empty-values="[0, '', null, undefined]"
            :value-on-clear="0"
            clearable
            check-strictly
            node-key="id"
            placeholder="请选择系统菜单"
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item prop="moduleName">
          <template #label>
            <span>
              模块名
              <el-tooltip content="模块名，即一级目录，例如 system、infra 等" placement="top">
                <Icon icon="ep:question-filled" />
              </el-tooltip>
            </span>
          </template>
          <el-input v-model="formData.moduleName" />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item prop="businessName">
          <template #label>
            <span>
              业务名
              <el-tooltip
                content="业务名，即二级目录，例如 dept、permission、dict 等"
                placement="top"
              >
                <Icon icon="ep:question-filled" />
              </el-tooltip>
            </span>
          </template>
          <el-input v-model="formData.businessName" />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item prop="className">
          <template #label>
            <span>
              类名称
              <el-tooltip
                content="类名称（首字母需大写），例如Dept、Menu、DictData 等"
                placement="top"
              >
                <Icon icon="ep:question-filled" />
              </el-tooltip>
            </span>
          </template>
          <el-input v-model.trim="formData.className" />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item prop="classComment">
          <template #label>
            <span>
              类描述
              <el-tooltip content="用作类描述，例如 部门、菜单、数据字典 等" placement="top">
                <Icon icon="ep:question-filled" />
              </el-tooltip>
            </span>
          </template>
          <el-input v-model="formData.classComment" />
        </el-form-item>
      </el-col>
    </el-row>

    <el-row v-if="formData.templateType === InfraCodegenTemplateTypeEnum.Tree">
      <el-col :span="24">
        <h4 class="form-header">树表信息</h4>
      </el-col>
      <el-col :span="12">
        <el-form-item prop="treeParentColumnId">
          <template #label>
            <span>
              父编号字段
              <el-tooltip content="树显示的父编码字段名， 如：parent_id" placement="top">
                <Icon icon="ep:question-filled" />
              </el-tooltip>
            </span>
          </template>
          <el-select
            v-model="formData.treeParentColumnId"
            :empty-values="[0, '', null, undefined]"
            :value-on-clear="0"
            placeholder="请选择父编号字段"
          >
            <el-option
              v-for="(column, index) in props.columns"
              :key="index"
              :label="column.columnName + '：' + column.columnComment"
              :value="column.id!"
            />
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item prop="treeNameColumnId">
          <template #label>
            <span>
              树名称字段
              <el-tooltip content="树节点的显示名称字段名， 如：name" placement="top">
                <Icon icon="ep:question-filled" />
              </el-tooltip>
            </span>
          </template>
          <el-select
            v-model="formData.treeNameColumnId"
            :empty-values="[0, '', null, undefined]"
            :value-on-clear="0"
            placeholder="请选择树名称字段"
          >
            <el-option
              v-for="(column, index) in props.columns"
              :key="index"
              :label="column.columnName + '：' + column.columnComment"
              :value="column.id!"
            />
          </el-select>
        </el-form-item>
      </el-col>
    </el-row>

    <el-row v-if="formData.templateType === InfraCodegenTemplateTypeEnum.Sub">
      <el-col :span="24">
        <h4 class="form-header">主表信息</h4>
      </el-col>
      <el-col :span="12">
        <el-form-item prop="masterTableId">
          <template #label>
            <span>
              关联的主表
              <el-tooltip content="关联主表（父表）的表名， 如：system_user" placement="top">
                <Icon icon="ep:question-filled" />
              </el-tooltip>
            </span>
          </template>
          <el-select
            v-model="formData.masterTableId"
            :empty-values="[0, '', null, undefined]"
            :value-on-clear="0"
            placeholder="请选择关联的主表"
          >
            <el-option
              v-for="(_table, index) in tableList"
              :key="index"
              :label="_table.tableName + '：' + _table.tableComment"
              :value="_table.id!"
            />
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item prop="subJoinColumnId">
          <template #label>
            <span>
              子表关联的字段
              <el-tooltip content="子表关联的字段， 如：user_id" placement="top">
                <Icon icon="ep:question-filled" />
              </el-tooltip>
            </span>
          </template>
          <el-select
            v-model="formData.subJoinColumnId"
            :empty-values="[0, '', null, undefined]"
            :value-on-clear="0"
            placeholder="请选择子表关联的字段"
          >
            <el-option
              v-for="(column, index) in props.columns"
              :key="index"
              :label="column.columnName + '：' + column.columnComment"
              :value="column.id!"
            />
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item prop="subJoinMany">
          <template #label>
            <span>
              关联的关系
              <el-tooltip content="主表与子表的关联关系" placement="top">
                <Icon icon="ep:question-filled" />
              </el-tooltip>
            </span>
          </template>
          <el-radio-group v-model="formData.subJoinMany">
            <el-radio value="Y">一对多</el-radio>
            <el-radio value="N">一对一</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>

<script setup lang="ts">
import * as CodegenApi from '@/api/infra/codegen'
import * as MenuApi from '@/api/system/menu'
import { PropType } from 'vue'
import { defaultProps, handleTree } from '@/utils/tree'
import { FormRules } from 'element-plus'
import {
  EnableStatusEnum,
  InfraCodegenTemplateTypeEnum,
  SystemMenuTypeEnum
} from '@/utils/constants'

defineOptions({ name: 'InfraCodegenGenerateInfoForm' })

const props = defineProps({
  table: {
    type: Object as PropType<Nullable<CodegenApi.CodegenTableVO>>
    // default: () => null
  },
  columns: {
    type: Array as unknown as PropType<CodegenApi.CodegenColumnVO[]>
    // default: () => null
  }
})

const { infra_codegen_scene, infra_codegen_template_type, infra_codegen_front_type } = useIntDict(
  DICT_TYPE.infra_codegen_scene,
  DICT_TYPE.infra_codegen_template_type,
  DICT_TYPE.infra_codegen_front_type
)
const disable_status_label = getDictLabel(DICT_TYPE.common_enable_status, EnableStatusEnum.Disabled)

const formRef = ref() // 表单ref
const formData = ref({
  templateType: undefined,
  frontType: undefined,
  scene: undefined,
  parentMenuId: undefined,
  moduleName: '',
  businessName: '',
  className: '',
  classComment: '',
  masterTableId: undefined,
  subJoinColumnId: undefined,
  subJoinMany: undefined,
  treeParentColumnId: undefined,
  treeNameColumnId: undefined
})
const formRules = reactive<FormRules>({
  templateType: [required],
  frontType: [required],
  scene: [required],
  moduleName: [required],
  businessName: [required],
  className: [required],
  classComment: [required],
  masterTableId: [required, not_zero],
  subJoinColumnId: [required, not_zero],
  subJoinMany: [required],
  treeParentColumnId: [required, not_zero],
  treeNameColumnId: [required, not_zero]
})

const tableList = ref<CodegenApi.CodegenTableSimpleVO[]>([])
const menuTree = ref<any[]>([])

// 外层传入props.table的对象变更也会监听并触发formData.value同步变更(保持与外层为同一对象)
watch(
  () => props.table,
  async (table) => {
    if (!table) return
    formData.value = table as any
    if (table.dataSourceConfigId >= 0) {
      tableList.value = await CodegenApi.getCodegenTableList(table.dataSourceConfigId)
    }
  },
  {
    immediate: true,
    deep: true
  }
)

const getMenuTree = async () => {
  let data = await MenuApi.getMenuSimpleList()
  data.forEach((menu) => {
    menu.name2 =
      menu.name + (menu.status === EnableStatusEnum.Enabled ? '' : ` [${disable_status_label}]`)
    menu.disabled = menu.type !== SystemMenuTypeEnum.Dir
  })
  menuTree.value = handleTree(data)
}

onMounted(() => {
  getMenuTree().catch(() => {})
})

defineExpose({
  validate: async () => await formValidate(formRef)
})
</script>

<style scoped lang="scss"></style>
